<?php
/**
 * CreateUser: zlh
 * CreateTime: 2022/4/11 11:52
 * Remark:
 */

namespace App\Service\Approval;

use App\Consts\Approval\ApprovalConsts;
use App\Consts\BaseConsts\BaseConsts;
use App\Consts\ResponseConsts\ResponseStatusConsts;
use App\Enum\ApprovalEnum\ApprovalEnums;
use App\Enum\ApprovalEnum\ApprovalRecodeEnum;
use App\Func\ResponseFunc;
use App\Func\TokenFuc;
use App\Models\Approval\OldDingTalkApprovalModel;
use App\Models\Approval\OldDingTalkApprovalTemplateModel;
use App\Models\File\FileModel;
use App\Models\Staff\StaffModel;
use App\Tools\DingTalk\DingTalkApprovalProcess;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Facades\DB;
use PHPUnit\Util\Exception;

class OldDingTalkApprovalService
{
    private StaffModel $_staffModel;
    private OldDingTalkApprovalModel $_oldDingTalkApprovalModel;
    private OldDingTalkApprovalTemplateModel $_oldDingTalkApprovalTempModel;

    public function __construct()
    {
        $this->_staffModel = new StaffModel();
        $this->_oldDingTalkApprovalModel = new OldDingTalkApprovalModel();
        $this->_oldDingTalkApprovalTempModel = new OldDingTalkApprovalTemplateModel();
    }


    /**
     * 这个方法可以用于发起审批 但是需要用户根据审批模板进行具体的配置
     * @param $approvals
     * @param $tmpId
     * @param $processType
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendOldApprovalProcess($approvals,$tmpId,$processType = 1)
    {
        // 验证写到这里是为了方便控制器层对这里进行多次调用，因为这里需要配置form-value
        // 获取发起人UserId
        $currentUser = TokenFuc::getCurrentStaffInfo();
        $userDingTalk = $this->_staffModel->getStaffDetail($currentUser['staff_id'],['staff_dingding_account'])['staff_dingding_account'];
        if(!$userDingTalk){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前发起人未绑定钉钉',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
        $processCode = $this->_oldDingTalkApprovalTempModel->getOldDingTalkApprovalTempInfo($tmpId,["ding_talk_approval_template_code"]);
//        if(!$processCode){
//            throw new HttpResponseException(ResponseFunc::returnJson(
//                'error',
//                null,
//                '当前模板ID不存在',
//                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
//            ));
//        }

        // 格式化
        foreach($approvals as $key => $value){
            // 获取dingTalkUserId
            $approvals[$key]['userIds'] = $value['user_ids'];
            $approvals[$key]['taskActionType'] = ApprovalEnums::getEnumMeaningByEnumCode($value['taskAction_type']);
            unset($approvals[$key]['taskAction_type']);
            unset($approvals[$key]['user_ids']);
        }

        // 获取钉钉用户ID
        foreach ($approvals as $key => $value){
             $res = $this->_staffModel->getStaffsInfo(explode(",",$value['userIds']),["staff_id","staff_dingding_account"]);
            $approvals[$key]['userIds'] = implode(",",array_column($res->toArray(),'staff_dingding_account'));
        }
        $jsonFile = [[
            'spaceId' => '3950635511',
            'fileName' => 'test(1).docx',
            'fileSize' => 13246,
            'fileType' => 'file',
            'fileId' => 58998701948,
        ]];
        // 配置并发送钉钉审批
        try {
            DB::beginTransaction();
            $sendApprovalProcessData = [
                'code' => 'PROC-DA942348-5B1A-438C-96A7-9F064D89D7D6',
                'originatorUserId' => $userDingTalk,
                'deptId' => -1,
                'approversV2' => $approvals,
                'formComponent' => [
                    [
                        'name' => '申请单位',
                        'value' => '总部'
                    ],
                    [
                        'name' => '备注',
                        'value' => '总部提交'
                    ],
                    [
                        'name' => '附件',
                        'value' => json_encode($jsonFile)
                    ],
                    [
                        'name' => '客户',
                        'value' =>
                            [
                                [
                                    [
                                        'name' => '新增或修改客户',
                                        'value' => '新增客户'
                                    ],
                                    [
                                        'name' => '客户名称',
                                        'value' => '内蒙古伊利实业集团股份有限公司'
                                    ]
                                ],
                                [
                                    [
                                        'name' => '新增或修改客户',
                                        'value' => '新增客户'
                                    ],
                                    [
                                        'name' => '客户名称',
                                        'value' => '内蒙古伊利实业集团股份有限公司广州分公司'
                                    ]
                                ]
                            ]
                    ]
                ]
            ];
            $processId =  DingTalkApprovalProcess::sendOldApprovalProcess($sendApprovalProcessData);
            // 添加审批详情
            $processInfo = DingTalkApprovalProcess::getContractApprovalProcessInfo($processId);

            if($processInfo->errcode){
                dump(1);
                throw new HttpResponseException(ResponseFunc::returnJson(
                    'error',
                    null,
                    $processInfo->msg,
                    ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                ));
            }else{
                $userIds = implode(",",@$processInfo->process_instance->approver_userids ?? []);
                // 整理审批实例数据
                $processArr = [
                    'ding_talk_approval_type_id' => $processType,
                    'ding_talk_approval_related_personnel_staff_ids'=>$userIds,
                    'originator_staff_id' => $currentUser['staff_id'],
                    'ding_talk_approval_process_id' =>$processId,
                    'created_at' => time()
                ];

                $res =  $this->_oldDingTalkApprovalModel->addTalkApproval($processArr);
                DB::commit();
                return $res;
            }
        }catch (Exception $exception){
            DB::rollBack();
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                $exception->getMessage(),
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }


    }

    /**
     * 这个方法可以用于发起审批 但是需要用户根据审批模板进行具体的配置
     * @param $approvals
     * @param $tmpCode
     * @param $processType
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendOldApprovalProcessByTmpCode($approvals,$tmpCode,$processType = 1)
    {
        // 验证写到这里是为了方便控制器层对这里进行多次调用，因为这里需要配置form-value
        // 获取发起人UserId
        $currentUser = TokenFuc::getCurrentStaffInfo();
        $userDingTalk = $this->_staffModel->getStaffDetail($currentUser['staff_id'],['staff_dingding_account'])['staff_dingding_account'];
        if(!$userDingTalk){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前发起人未绑定钉钉',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
        $processCode = $this->_oldDingTalkApprovalTempModel->getOldDingTalkApprovalTempInfo($tmpCode,["ding_talk_approval_template_code"]);
        if(!$processCode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前模板ID不存在',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }

        // 格式化
        foreach($approvals as $key => $value){
            // 获取dingTalkUserId
            $approvals[$key]['userIds'] = $value['user_ids'];
            $approvals[$key]['taskActionType'] = ApprovalEnums::getEnumMeaningByEnumCode($value['taskAction_type']);
            unset($approvals[$key]['taskAction_type']);
            unset($approvals[$key]['user_ids']);
        }

        // 获取钉钉用户ID
        foreach ($approvals as $key => $value){
            $res = $this->_staffModel->getStaffsInfo(explode(",",$value['userIds']),["staff_id","staff_dingding_account"]);
            $approvals[$key]['userIds'] = implode(",",array_column($res->toArray(),'staff_dingding_account'));
        }

        // 配置并发送钉钉审批
        try {
            DB::beginTransaction();
            $sendApprovalProcessData = [
                'code' => $processCode['ding_talk_approval_template_code'],
                'originatorUserId' => $userDingTalk,
                'deptId' => -1,
                'approversV2' => $approvals,
                'formComponent' => [
                    [
                        'name' => '合同标题',
                        'value' => '123'
                    ],
                    [
                        'name' => '合同类型',
                        'value' => 'gg'
                    ],
                    [
                        'name'=>'合同金额',
                        'value' => 100000
                    ],
                    [
                        'name' => '合同相对方',
                        'value' => 'test'
                    ]
                ]
            ];
            $processId =  DingTalkApprovalProcess::sendOldApprovalProcess($sendApprovalProcessData);
            // 添加审批详情
            $processInfo = DingTalkApprovalProcess::getContractApprovalProcessInfo($processId);
            if($processInfo->errcode){
                throw new HttpResponseException(ResponseFunc::returnJson(
                    'error',
                    null,
                    $processInfo->msg,
                    ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                ));
            }else{
                $userIds = implode(",",$processInfo->process_instance->approver_userids);
                // 整理审批实例数据
                $processArr = [
                    'ding_talk_approval_type_id' => $processType,
                    'ding_talk_approval_related_personnel_staff_ids'=>$userIds,
                    'originator_staff_id' => $currentUser['staff_id'],
                    'ding_talk_approval_process_id' =>$processId,
                    'created_at' => time()
                ];

                $res =  $this->_oldDingTalkApprovalModel->addTalkApproval($processArr);
                DB::commit();
                return $res;
            }
        }catch (Exception $exception){
            DB::rollBack();
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                $exception->getMessage(),
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }


    }


    /**
     * 获取用户审核个数
     * @param $userId

     */
    public function getUserApprovalToDoNumber($userId)
    {
        $userDingTalk = $this->_staffModel->getStaffDetail($userId,['staff_dingding_account'])['staff_dingding_account'] ?? 0;
        if(!$userDingTalk){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前用户未绑定钉钉',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
        return DingTalkApprovalProcess::getUserApprovalProcessCount($userDingTalk);
    }

    public function getDingTalkApprovalInfo($processId)
    {
        $res =  DingTalkApprovalProcess::getContractApprovalProcessInfo($processId);
        dd($res);
    }

    public function getApprovalLogBySourceIdSourceType($sourceId,$sourceType){
        $aLog = $this->_oldDingTalkApprovalModel->getTalkApprovalLogBySourceIdSourceType($sourceId,$sourceType);
        $fmtFC = @json_decode($aLog->form_component,true) ?? [];
//        $fm = new FileModel();
//        foreach($fmtFC as $key => $value){
//            if($value['name'] == "附件"){
//                $fmtFC[$key]['value'] = $fm->getFilesByIds(explode(',',$value['value']));
//            }
//        }
        return [
            'form_component' => $fmtFC,
            'finish_time' => @$aLog->finish_time ?? "",
            'operation_records' => @json_decode($aLog->operation_records,true) ?? [],
        ];
    }



    public function getDingTalkApprovalRecode($processId)
    {
        $res =  DingTalkApprovalProcess::getContractApprovalProcessInfo($processId);
        $processInstance = $res->process_instance;
        $operationRecords = $processInstance->operation_records;
//        $formComponent = [];
        $operationRecordsFmt = [];
        $sm = new StaffModel();
        foreach($operationRecords as $value){
            $staffName = $sm->getStaffDetailByDingTalkId($value->userid)['staff_name'] ?? "-";
            $operationRecordsFmt[] = [
                "date" => $value->date,
                "operation_type" => ApprovalRecodeEnum::getEnumMeaningByEnumCode($value->operation_type),
                "operation_result" => ApprovalRecodeEnum::getEnumByEnumCode($value->operation_result),
                "remark" => @$value->remark,
                "staff_name" => $staffName,
                "staff_id" => $value->userid,
                "attachments" => @$value->attachments
            ];
        }

//        foreach($processInstance->form_component_values as $value){
//            if($value->value != "null" && $value->name != "附件"){
//                $formComponent[] = [
//                    'name' => $value->name,
//                    'value' => $value->value
//                ];
//            }
//        }
        return  [
            'create_time' => @$processInstance->create_time,
            'finish_time' => @$processInstance->finish_time,
            'operation_records' => $operationRecordsFmt
        ];
        return ResponseFunc::returnJson(
            'ok',
            [
                'create_time' => @$processInstance->create_time,
                'finish_time' => @$processInstance->finish_time,
                'operation_records' => $operationRecordsFmt
            ],
            "获取审批详情成功",
            ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
        );
    }
}